﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;

namespace ImageLibrary
{
    public partial class ImageProcessing
    {
        #region 字段信息
        //输入路径
        private string path;
        //要裁剪的宽度
        private int width;
        //要裁剪的宽度
        private int heigth;
        //图片资源存放
        private Image image;
        public Image Imaeg{set{image=value;}get{return image;}}
        //原始图片旋转度
        private int rotate;
        //xml配置
        private ImageConfig ImConfig;

        
        #endregion

        #region 构造函数
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="path">图片路径</param>
        /// <param name="outpath">图片输出路径</param>
        /// <param name="width">图片宽度</param>
        /// <param name="heigth">图片高度</param>
        public ImageProcessing(string path, ImageConfig config)
        {
            this.ImConfig = config;
            this.path = path; 
            this.width = config.Width; 
            this.heigth =config.Heigth;
            //暂时用延迟来防止未复制完成。 此方法不完美；
            System.Threading.Thread.Sleep(1000);
            if (!System.IO.File.Exists(path)) { throw new Exception("文件不存在"); }
            Image img = System.Drawing.Image.FromFile(path);
           // Bitmap img = new System.Drawing.Bitmap(path);
            // System.Windows.Forms.MessageBox.Show(rotate.ToString());
            image = new System.Drawing.Bitmap(img);
            this.rotate = readPictureDegree(img);//获取旋转角度；
            img.Dispose();

            
        }
        #endregion

        #region 图片处理
        /// <summary>
        /// 处理图片
        /// </summary>
        public void Processing()
        {
            const int ONE_INCH = 2;//1寸
            const int TWO_INCH = 3;//2寸
            const int CUT = 0;//裁剪
            const int ZOOM = 1;//居中
            //图片自动旋转
            AutoKiRotate();
            //图片裁剪
            if(ImConfig.Layout == CUT )//裁剪
            {
               DoConvert(width, heigth); 
            }
           
            if(ImConfig.Layout == ZOOM)//居中
            {
               ZoomPic();
            }
           
            if (ImConfig.Type == ONE_INCH)//一寸
            {
                OneInch(400,600);//背景 400 * 600
            }
            if (ImConfig.Type == TWO_INCH)//二寸
            {
                OneInch(500, 700);//背景 400 * 600
            }
        }
        #endregion

        #region 图片居中缩放
        /// <summary>
        /// 对上传的图片进行等比缩放
        /// </summary>
        /// http://www.cnblogs.com/babycool
        /// <param name="fromFile">获取文件流Stream</param>
        /// <param name="fileSaveUrl">缩略图保存完整路径</param>
        /// <param name="targetWidth">模板宽度</param>
        /// <param name="targetHeight">模板高度</param>
        public  void ZoomPic()
        {
            Double targetWidth, targetHeight;
            if (image.Width > image.Height)
            {
                targetWidth = heigth; targetHeight = width;
            }
            else 
            {
                targetWidth = width; targetHeight = heigth;
            }
            //原始图片（获取原始图片创建对象，并使用流中嵌入的颜色管理信息）
            Image initImage = this.image;
            //原图宽高均小于模版，不作处理，直接保存
            if (initImage.Width <= targetWidth && initImage.Height <= targetHeight)
            {
                //返回
                return;
            }
            else
            {
                //缩略图宽、高计算
                double newWidth = initImage.Width;
                double newHeight = initImage.Height;
                //宽大于高或宽等于高（横图或正方）
                if (initImage.Width > initImage.Height || initImage.Width == initImage.Height)
                {
                    //如果宽大于模版
                    if (initImage.Width > targetWidth)
                    {
                        //宽按模版，高按比例缩放
                        newWidth = targetWidth;
                        newHeight = initImage.Height * (targetWidth / initImage.Width);
                    }
                }
                //高大于宽（竖图）
                else
                {
                    //如果高大于模版
                    if (initImage.Height > targetHeight)
                    {
                        //高按模版，宽按比例缩放
                        newHeight = targetHeight;
                        newWidth = initImage.Width * (targetHeight / initImage.Height);
                    }
                }
                //如果 NEW 图片宽度高度大于 模版宽度高度.在次缩放
                Double w = newWidth, h = newHeight;
                if(newWidth >targetWidth)
                {
                     w = targetWidth;
                     h = (targetWidth / newWidth) * newHeight;
                }else if(newHeight > targetHeight)
                {
                     h = targetHeight;
                     w = (targetHeight / newHeight) * newWidth;
                }
                Rectangle dsRec = new Rectangle((int)(targetWidth-w)/2, (int)(targetHeight-h)/2, (int)w, (int)h);
                Rectangle adRec = new Rectangle(0, 0, initImage.Width, initImage.Height);
                //生成新图
                //新建一个bmp图片
                //Image newImage = new Bitmap((int)newWidth, (int)newHeight);
                Image newImage = new Bitmap((int)targetWidth, (int)targetHeight);
                //新建一个画板
                Graphics newG = Graphics.FromImage(newImage);
                //设置质量
                newG.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                newG.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                //置背景色
                newG.Clear(Color.White);
                //画图
                //newG.DrawImage(initImage, new Rectangle(0, 0, newImage.Width, newImage.Height), new Rectangle(0, 0, initImage.Width, initImage.Height), System.Drawing.GraphicsUnit.Pixel);
                newG.DrawImage(initImage,dsRec, adRec, System.Drawing.GraphicsUnit.Pixel);
                //保存缩略图
                //newImage.Save(fileSaveUrl, System.Drawing.Imaging.ImageFormat.Jpeg);
 
                //释放资源
                image.Dispose();
                this.image = newImage;
                newG.Dispose();
                //newImage.Dispose();
                initImage.Dispose();
            }

        }
        #endregion

        #region 自定义裁剪并缩放
        /// <summary>  
        /// 图片转换（裁剪并缩放）方法原理先得到输入的宽和高的比例 
        ///                       来计算裁剪原图片的比例 然后缩放 
        /// </summary>  
        /// <param name="ASrcFileName">源文件名称</param>  
        /// <param name="ADestFileName">目标文件名称</param>  
        /// <param name="AWidth">转换后的宽度（像素）</param>  
        /// <param name="AHeight">转换后的高度（像素）</param>  
        /// <param name="AQuality">保存质量（取值在1-100之间）</param>  
        public void DoConvert(int AWidth, int AHeight)
        {
            Image ASrcImg = image;
            if (ASrcImg.Width <= AWidth && ASrcImg.Height <= AHeight)
            {//图片的高宽均小于目标高宽，直接保存  
                this.image = ASrcImg;
                //ASrcImg.Save(outpath);
                return;
            }
            if(ASrcImg.Width > ASrcImg.Height){
                int temp;
                temp = AHeight;
                AHeight = AWidth;
                AWidth = temp;
            }

            double ADestRate = AWidth * 1.0 / AHeight;
            double ASrcRate = ASrcImg.Width * 1.0 / ASrcImg.Height;
            //裁剪后的宽度  
            double ACutWidth = ASrcRate > ADestRate ? (ASrcImg.Height * ADestRate) : ASrcImg.Width;
            //裁剪后的高度  
            double ACutHeight = ASrcRate > ADestRate ? ASrcImg.Height : (ASrcImg.Width / ADestRate);
            //待裁剪的矩形区域，根据原图片的中心进行裁剪  它指定 image 对象中要绘制的部分。
            Rectangle AFromRect = new Rectangle(Convert.ToInt32((ASrcImg.Width - ACutWidth) / 2), Convert.ToInt32((ASrcImg.Height - ACutHeight) / 2), (int)ACutWidth, (int)ACutHeight);
            //目标矩形区域  它指定所绘制图像的位置和大小。将图像进行缩放以适合该矩形。
            Rectangle AToRect = new Rectangle(0, 0, AWidth, AHeight);
            //创建画板
            Image ADestImg = new Bitmap(AWidth, AHeight);
            
            Graphics ADestGraph = Graphics.FromImage(ADestImg);
            ADestGraph.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            ADestGraph.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            ADestGraph.DrawImage(ASrcImg, AToRect, AFromRect, GraphicsUnit.Pixel);
            ADestGraph.Dispose();
            ASrcImg.Dispose();
            //画玩图后保存到image
            this.image.Dispose();
            this.image = ADestImg;

        }
        #endregion

        #region 一寸照片
        public void OneInch(int pageWidth,int pageHeight) 
        {
            //创建画板 6寸相纸
            Image tempImg;
            tempImg = image.Width > image.Height ? new Bitmap(pageHeight, pageWidth)
                                                  : new Bitmap(pageWidth, pageHeight);
            Graphics ADestGraph = Graphics.FromImage(tempImg);
            ADestGraph.Clear(Color.White); //清空画布并以白色背景色填充
            int Margin = 2, x = Margin, y = Margin;
            // Draw image to screen.
            int w,h;
            if (image.Width > image.Height)
            {
                w = heigth;
                h = width;
            }
            else
            {
                w = width;
                h = heigth;
            }
            for (int j = 1; j <= 3; j++)
            {
                for (int i = 1; i <= 3; i++)
                {
                    ADestGraph.DrawImage(image, x, y);
                    x += w + Margin;
                }
                x = Margin;
                y += h + Margin;
            }
            ADestGraph.Dispose();
            this.image.Dispose();
            this.image = tempImg;
            //tempImg.Dispose();
        }
        #endregion

        #region 保存输出图片
        /// <summary>
        /// 保存图片到文件
        /// </summary>
        /// <param name="OutPath">保存路径</param>
        public void Save(string OutPath) {
            /// <param name="AQuality">保存质量（取值在1-100之间）</param>
            int AQuality = 100;
            ImageCodecInfo[] AInfos = ImageCodecInfo.GetImageEncoders();
            ImageCodecInfo AInfo = null;
            foreach (ImageCodecInfo i in AInfos)
            {
                if (i.MimeType == "image/jpeg")
                {
                    AInfo = i;
                    break;
                }
            }
            //设置转换后图片质量参数  
            EncoderParameters AParams = new EncoderParameters(1);
            AParams.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)AQuality);
            //保存  
            this.image.Save(OutPath, AInfo, AParams);       
        }
        #endregion

        #region 获取原图旋转角度(IOS和Android相机拍的照片)
        /// <summary>  
        /// 获取原图旋转角度(IOS和Android相机拍的照片)  
        /// </summary>  
        /// <param name="path"></param>  
        /// <returns></returns>  
        public  int readPictureDegree(Image image)
        {
            int rotate = 0;
            //using (var image = System.Drawing.Image.FromFile(path))
            {
                foreach (var prop in image.PropertyItems)
                {
                    if (prop.Id == 0x112)
                    {
                        if (prop.Value[0] == 6)
                            rotate = 90;
                        if (prop.Value[0] == 8)
                            rotate = -90;
                        if (prop.Value[0] == 3)
                            rotate = 180;
                        prop.Value[0] = 1;
                    }
                }
            }
            return rotate;
        }
        #endregion

        #region 图片旋转逻辑
        
        private void AutoKiRotate() 
        {
            if (rotate == 90)
            {
                KiRotate(RotateFlipType.Rotate90FlipNone);
            }
            else if (rotate == -90)
            {
                KiRotate(RotateFlipType.Rotate270FlipNone);
            }
            else if (rotate == 180)
            {
                KiRotate(RotateFlipType.Rotate180FlipNone);
            }   
        }
        #endregion

        #region 图片旋转
        /// <summary>  
        /// 旋转  解释：
        ///顺时针旋转90度 RotateFlipType.Rotate90FlipNone
        ///逆时针旋转90度 RotateFlipType.Rotate270FlipNone
        ///水平翻转 RotateFlipType.Rotate180FlipY
        ///垂直翻转 RotateFlipType.Rotate180FlipX
        /// </summary>  
        /// <param name="path"></param>  
        /// <param name="rotateFlipType"></param>  
        /// <returns></returns>  
        public  bool KiRotate(RotateFlipType rotateFlipType)
        {
            try
            {
                
                {
                    this.image.RotateFlip(rotateFlipType);
                    //image.Save(path);
                }
                return true;
            }
            catch (Exception )
            {
                return false;
            }
        }
        #endregion

        #region 图片合并
        public void PicJoin() 
        {
           
        }
        
        #endregion
    }
}
